package app

import (
	"fmt"
	"os"

	"git.sr.ht/~mil/mobsql/dbschema"
	"git.sr.ht/~mil/mobsql/logger"
	"git.sr.ht/~mil/mobsql/utildownload"
	"git.sr.ht/~mil/mobsql/utilfiles"
)

// SourcesetLoad loads the given sourceset to the database
func SourcesetLoad(m *MDB, sourceset []int) (*SourcesetOpResult, error) {
	logger.Infof("Running Load against %d sources", len(sourceset))
	defer logger.Infof("Running Load against %d sources ok", len(sourceset))

	for i, mdbid := range sourceset {
		logger.Infof("Loading mdbid %d (%d of %d)", mdbid, i+1, len(sourceset))
		if url, err := m.QueryValue("select url from _vsources where mdbid = ?", []any{mdbid}); err != nil {
			return nil, fmt.Errorf("Error mdbid %s querying URL for mdbid: %w", mdbid, err)
		} else if filepath, downloadedURLFirstPass, err := utildownload.DownloadURLCached(url, ".zip"); err != nil {
			return nil, fmt.Errorf("Error mdbid %s downloading URL %s for mdbid: %w", mdbid, url, err)
		} else if err := m.loadGTFSZipToDB(filepath, mdbid); err != nil {
			return nil, fmt.Errorf("Error mdbid %s loading downloaded zip to DB: %w", mdbid, err)
		} else {
			logger.Infof("Loading mdbid %d ok; used cache for URL download (%v)", mdbid, !downloadedURLFirstPass)
		}
	}
	return &SourcesetOpResult{
		Operation: "load",
		Success:   true,
		Mdbids:    sourceset,
	}, nil
}

func (m *MDB) loadGTFSZipToDB(zipFSPath string, sourceName int) error {
	logger.Infof("Loading %s to DB with source name: %d", zipFSPath, sourceName)
	defer logger.Infof("Loaded %s to DB with source name: %d ok", zipFSPath, sourceName)

	validGTFSFiles := []string{
		"agency.txt", "calendar.txt", "calendar_dates.txt", "frequencies.txt",
		"routes.txt", "stops.txt", "stop_times.txt", "transfers.txt", "trips.txt",
	}

	if dir, err := utilfiles.TempDir("mobroute_tempdir"); err != nil {
		return err
	} else if err := utilfiles.UnzipZipArchive(validGTFSFiles, zipFSPath, dir); err != nil {
		return err
	} else {
		logger.Warnf("Loaded GTFS Archive %s to temporary directory: %s", zipFSPath, dir)

		for _, table := range dbschema.Schema.TablesGTFS {
			logger.Warnf("Loading table: %s", table.TableSpec.Table)
			if err := m.importTableFromSpec(&table, map[string]any{"source": sourceName}, dir, sourceName); err != nil {
				return err
			}
			logger.Warnf("Loading table: %s complete", table.TableSpec.Table)
		}
		os.RemoveAll(dir)
		return nil
	}
}
